home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
CP14.ARJ
/
CPFUNCTS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-20
|
10KB
|
524 lines
/*
LISTING 3
*/
/* function module for the program 'cp'
the cp program must be compiled with the large model */
/***********************************************************
cpfuncts.c - function module for the program 'cp'
copyright 1987, Stewart A. Nutter
written by: Stewart A. Nutter
***********************************************************/
#define MAINMODULE 0
#include "cp.h" /* v1.1 */
/* v1.1 Global prototypes */
int find_mod(char *buf);
void getstats(void);
int doprint(int n);
void pagebreak(void);
void leftmargin(void); /* v1.4 */
char getnext(FILE *stream);
void pushc(char c);
int strcheck(char c);
int addlist(struct Func_list *p, char *buf, int cnt);
/* v1.1 local prototypes */
static char getchars(FILE *stream);
static void setpage(struct Mod_list *ptr);
static void pblock(char *pre, char *fptr, char *mptr, char *sptr, int cnt);
static int recur_chk(char *buf);
/* getnext - get the next character from the stream */
char getnext(FILE *stream)
{
register char c;
static int qflag = 0, cflag = 0, eflag = 0;
static int dflag = 0, aflag = 0, ncnt = 0;
static int fp;
int b, done;
done = 1;
do {
if ((qflag | cflag | eflag | dflag | aflag) == 0)
done = 1;
c = getchars(stream);
/* process escape sequence characters */
if (eflag && c != 0x1a) {
if (c >= '0' && c <= '7' && ncnt < 3)
ncnt++;
else {
/* had less than the 3 octal digits */
if (ncnt < 3 && ncnt > 0)
pushc(c);
ncnt = 0;
eflag = 0;
}
} else if (cflag && c != 0x1a) { /* skipping a comment */
if (firstcmt == 1) {
if (c != '\n' && strlen(filecmt) < (width - 14)) {
filecmt[fp] = c;
fp++;
filecmt[fp] = 0;
} else {
do { /* remove extraneous spaces and tabs */
b = getchars(stream);
}
while (b == ' ' || b == '\t');
pushc(b);
filecmt[fp++] = ' ';
filecmt[fp] = '\0';
}
}
if (c == '*') {
b = getchars(stream);
if (b == '/') {
firstcmt = 2; /* done with the comment */
if (fp > 0)
filecmt[fp - 1] = 0; /* terminate the line */
cflag = 0;
} else
pushc(b);
}
} else if (qflag && c != 0x1a) { /* skipping a string */
if (c == 0x27)
eflag = 1;
else if (c == '\"') {
pushc(0x1b);
qflag = 0;
}
} else if (dflag && c != 0x1a) { /* defines/includes etc. */
if (c == '\n')
dflag = 0;
} else if (aflag && c != 0x1a) { /* skip a character */
if (c == 0x27) {
aflag = 0;
pushc(0x1b);
} else if (c == '\\')
eflag = 1;
} else {
switch (c) {
case '\"':
qflag = 1;
break;
case 0x27:
aflag = 1;
break;
case '#':
dflag = 1;
break;
case '/':
b = getchars(stream);
if (b == '*') {
/* this is the first comment of the file */
if (firstcmt == 0) {
firstcmt = 1;
filecmt[0] = 0;
fp = 0;
}
cflag = 1;
} else {
pushc(b);
}
break;
}
}
if (aflag || dflag || qflag || eflag || cflag)
done = 0;
}
while (!done && c != 0x1a);
if (c == 0x1a) {
ncnt = 0;
aflag = 0;
dflag = 0;
qflag = 0;
eflag = 0;
cflag = 0;
}
return (c);
}
/* getchars - read inputs from the file */
static char getchars(FILE *stream)
{
register char c;
if (pp != pc)
c = *--pp;
else {
c = fgetc(stream);
if (c == (char) EOF) /* v1.1 */
c = 0x1a;
if (c == 0x0a) {
pMnames->length++;
pMnames->size++; /* count the unseen <cr> */
}
pMnames->size++;
}
return (c);
}
/* pushc - save the char. in a last in first out stack */
void pushc(char c)
{
if ((pp - pc) < 1000)
*pp++ = c;
else {
fprintf(stderr, "\nProgram syntax error:");
fprintf(stderr, " Too many pushed characters.\n");
exit(1);
}
}
/* addlist - add the name to the list if different */
/* and if not one of the 'c' key words */
#define KEYS 5
int addlist(struct Func_list *p, char *buf, int cnt)
{
int i, ret;
static char *keywords[KEYS] =
{
"while",
"if",
"for",
"switch",
"return",
};
for (i = 0; i < KEYS && strcmp(buf, keywords[i]) != 0; i++);
if (i < KEYS)
return (0);
for (i = 0; i < cnt && strcmp(buf, p->name); i++)
p++;
if (i == cnt) {
ret = 1;
if ((pFlist->name = strdup(buf)) == NULL) {
fprintf(stderr, "Ran out of memory.\n");
exit(1);
}
pFlist->used = 1;
pFlist++; /* point to the next empty cell */
Fqty++;
if (Fqty > MAXFNCTS) {
fprintf(stderr, "Too many functions.\n");
exit(1);
}
} else {
ret = 0;
p->used++;
}
return (ret);
}
/* find_mod - return the index of the linked list for
the indicated function. A -1 means that
the function name was not found in the list */
int find_mod(char *buf)
{
int lo, hi, mid;
int d;
lo = 0;
hi = Mqty - 1;
mid = (hi + lo) / 2;
while (1) {
d = strcmp(buf, pm[mid]->function);
if (d == 0)
break;
if (lo >= hi) {
mid = -1;
break;
}
if (d < 0) {
hi = mid - 1;
} else {
lo = mid + 1;
}
mid = (hi + lo) / 2;
}
return (mid);
}
/* doprint - print the function name and sub - functions */
static char lib[] =
{"(library)"};
static char use[] =
{"Used="};
static char fct[] =
{"Functs="};
int doprint(int n)
{
int i, j, k, l, ret;
struct Mod_list *p;
struct Func_list *q;
l = n;
p = pm[l];
/* add function to list for recursion check */
rlist[depth] = p->function;
pagebreak();
setpage(pm[l]);
ret = page - 1;
pblock(bfr, p->function, (p->name)->name, fct, p->qty);
depth++;
strcat(bfr, " |");
k = p->qty;
for (j = 0, q = p->ptr; j < k; j++, q++) {
pagebreak();
i = find_mod(q->name);
if (recur_chk(q->name)) {
leftmargin(); /* v1.4 */
printf("%s\n", bfr); /* v1.4 */
if (i >= 0)
setpage(pm[i]);
pblock(bfr, q->name, "(recursive)", "", 0);
line++;
} else {
if (i >= 0) {
if (pm[i]->used == 1) {
/* got a new function */
leftmargin(); /* v1.4 */
printf("%s\n", bfr); /* v1.4 */
line++;
doprint(i); /* used only once */
} else {
/* a previously defined function */
leftmargin(); /* v1.4 */
printf("%s\n", bfr); /* v1.4 */
setpage(pm[i]);
pblock(bfr, q->name, "(defined)",
use, q->used);
line++;
}
} else {
/* a library function */
leftmargin(); /* v1.4 */
printf("%s\n", bfr); /* v1.4 */
pblock(bfr, q->name, lib, use, q->used);
line++;
}
}
}
/* remove the function from the recursion list */
rlist[depth] = NULL;
bfr[strlen(bfr) - 4] = 0;
depth--;
return (ret);
}
/* getstats - get the number of times each
function is used */
void getstats(void)
{
register int i;
int j;
register struct Func_list *p;
p = Flist;
for (i = 0; i < Fqty; i++) {
j = find_mod(p->name); /* see if the name exists */
if (j >= 0)
pm[j]->used += p->used;
p++;
}
}
/* pblock - print a function block */
static void pblock(char *pre, char *fptr, char *mptr, char *sptr, int cnt)
{
leftmargin(); /* v1.4 */
printf("%s %s\n", pre, tline);
leftmargin();
printf("%s-+%-25s|\n", pre, fptr);
leftmargin();
printf("%s |%-12s %8s%3d |\n",
pre, mptr, sptr, cnt);
leftmargin();
printf("%s %s\n", pre, tline);
line += 4;
}
/* pagebreak - check for a page break and if so
then print the page header */
void pagebreak(void)
{
int i;
static char title[] =
{"C PRINTER - (c) 1987, 1988 rev. 1.2"};
if (pl == 0 && line == 9999) {
printf("\n\n\n\n"); /* v1.4 */
line = 0;
} else if (pl != 0) {
if (line > (pl - 11)) {
printf("%c", 0x0c); /* v1.4 */
line = 0;
}
if (line == 0) {
leftmargin(); /* v1.4 */
printf("%s", title); /* v1.4 */
for (i = strlen(title); i < width - 10; i++)
fputc(' ', stdout); /* v1.4 */
printf("Page:%4d\n", page); /* v1.4 */
leftmargin(); /* v1.4 */
for (i = 0; i < width; i++)
fputc('-', stdout); /* v1.4 */
printf("\n\n"); /* v1.4 */
line = 3;
page++;
}
}
}
/* recur_chk - check if the function just called
is one being processed */
int recur_chk(char *buf)
{
register char **p;
int ret;
p = rlist;
while (*p != NULL && strcmp(*p, buf)) {
p++;
}
if (*p == NULL)
ret = 0; /* the function was not in the list */
else
ret = 1; /* found it */
return ret;
}
/* setpage - put the current page number
into the linked page list */
static void setpage(struct Mod_list *ptr)
{
struct Pages *p;
p = ptr->pg;
if (p == NULL) {
p = (struct Pages *) malloc(sizeof(struct Pages));
if (p == NULL) {
fprintf(stderr,
"Ran out of memory for page # list.\n");
exit(1);
}
ptr->pg = p;
p->next = NULL;
p->pg = page - 1;
} else {
while (p->next != NULL)
p = p->next;
p->next = (struct Pages *) malloc(sizeof(struct Pages));
if (p->next == NULL) {
fprintf(stderr,
"Ran out of memory for page # list.\n");
exit(1);
}
p = p->next;
p->next = NULL;
p->pg = page - 1;
}
}
/* strcheck - check if the character is
* in the variable name set
*/
int strcheck(char c)
{
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
c == '_' || (c >= '0' && c <= '9'))
return (1);
else
return (0);
}
void stop(void)
{
printf("hello");
}
/* print the left margin for the printout */
void leftmargin(void) /* v1.4 */
{
register int i;
for (i = 0; i < lm; i++)
fputc(' ', stdout); /* v1.4 */
}